<template>
  <div class="upload-file-new">
    <el-upload
      multiple
      :action="uploadFileUrl"
      :before-upload="handleBeforeUpload"
      :limit="limit"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :headers="headers"
      class="upload-file-uploader"
      ref="fileUploadRef"
    >
      <!-- 上传按钮 -->
      <div class="upload-box">
        <div class="upload-btn">
          <div class="add-btn"></div>
          <p class="text">点击上传</p>
        </div>
        <div class="annex-tips">
          <h3>图片/附件要求</h3>
          <h4>上传完善好的附件，支持上传文件{{tips}}</h4>
        </div>
      </div>
    </el-upload>
    <div class="file-list">
      <div v-for="(item, index) of uploadList" :key="index" class="file-item">
        <div>{{item}}</div>
        <div class="btns">
          <el-tooltip placement="top" content="删除">
            <img src="./assets/delete.png" @click="deleteItem(item)" alt="" />
          </el-tooltip>
          <el-tooltip placement="top" content="预览" v-if="item.includes('.pdf')">
            <img src="./assets/see.png" @click="seeItem(item)" alt="" />
          </el-tooltip>
          <el-tooltip placement="top" content="下载" v-else>
            <img src="./assets/download.png" @click="seeItem(item)" alt="" />
          </el-tooltip>
        </div>
      </div>
    </div>

    <el-dialog v-model="dialogVisible" title="预览" width="1200px" append-to-body>
      <iframe :src="fileUrl" class="pdf-box" />
    </el-dialog>
  </div>
</template>
<script setup lang="ts">
import {defineComponent} from "vue";
import {globalHeaders} from "@/utils/request";
import {propTypes} from "@/utils/propTypes";

const props = defineProps({
  modelValue: [String, Object, Array],
  // 数量限制
  limit: propTypes.number.def(5),
  // 大小限制(MB)
  fileSize: propTypes.number.def(5),
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  fileType: propTypes.array.def(["doc", "docx", "ppt", "jpg", "pdf"]),
  // 是否显示提示
  isShowTip: propTypes.bool.def(true),
  // 文件
  fileList: {
    type: Array,
    default: () => []
  }
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadFileUrl = ref(baseUrl + "/resource/oss/upload"); // 上传文件服务器地址
const headers = ref(globalHeaders());
const emit = defineEmits(['success']);
const number = ref(0);
const uploadList = ref<string[]>([]);
const fileUploadRef = ref<ElUploadInstance>();
const dialogVisible = ref(false);
const fileUrl = ref('');
const tips = computed(() => props.fileType.join(','));

// 上传前校检格式和大小
const handleBeforeUpload = (file: any) => {
  // 校检文件类型
  if (props.fileType.length) {
    const fileName = file.name.split('.');
    const fileExt = fileName[fileName.length - 1];
    const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
    if (!isTypeOk) {
      proxy?.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);
      return false;
    }
  }
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      proxy?.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  proxy?.$modal.loading("正在上传文件，请稍候...");
  number.value++;
  return true;
}

// 文件个数超出
const handleExceed = () => {
  proxy?.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}

// 上传失败
const handleUploadError = () => {
  proxy?.$modal.msgError("上传文件失败");
}

// 上传成功回调
const handleUploadSuccess = (res: any, file: UploadFile) => {
  if (res.code === 200) {
    uploadList.value.push(res.data.url);
    proxy?.$modal.msgSuccess("上传文件成功");
    emit('success', uploadList.value)
  } else {
    number.value--;
    proxy?.$modal.closeLoading();
    proxy?.$modal.msgError(res.msg);
    fileUploadRef.value?.handleRemove(file);
  }
  proxy?.$modal.closeLoading();
}

const deleteItem = (item: string) => {
  uploadList.value = uploadList.value.filter((sItem: string) => sItem !== item);
  emit('success', uploadList.value)
}

const seeItem = (item: string) => {
  if (!item.includes('.pdf')) return window.open(item);
  dialogVisible.value = true;
  fileUrl.value = item;
}

watch(() => props.fileList, (val: any[]) => {
  uploadList.value = val
})

defineComponent({name: 'FileUploadNew'})
</script>

<style scoped lang="scss">
.upload-box {
  display: flex;
  align-items: center;
}

.upload-btn {
  width: 96px;
  height: 96px;
  padding-top: 20px;
  background: #F9F9F9;
  border-radius: 8px;
  border: 1px dashed #BFBFBF;
  cursor: pointer;

  .add-btn {
    width: 30px;
    height: 30px;
    margin: 0 auto;
    background: url('./assets/add.png') no-repeat center;
  }

  .text {
    text-align: center;
    color: #FF4350;
  }
}

.annex-tips {
  margin-left: 15px;

  h4 {
    margin-top: 10px;
    color: #999;
  }
}

.file-list {

  .file-item {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;

    .btns {
      width: 40px;
      height: 40px;
      margin-left: 30px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      line-height: 42px;
      cursor: pointer;

      img {
        width: 16px;
        cursor: pointer;
      }
    }
  }
}

.pdf-box {
  width: 100%;
  height: 650px;
}
</style>
